// 网银APP软件服务端
#include "../_public.h"

CLogFile logfile;      // 服务程序的运行日志
CTcpServer TcpServer;  // 创建服务端对象

void FathEXIT(int sig);
void ChldEXIT(int sig);

bool bsession = false;		// 客户端是否已成功登录
bool _main(const char *str1, char* str2);
bool srv001(const char *str1, char* str2);
bool srv002(const char *str1, char* str2);

int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		printf("Using:./demo12 port logfile\nExample:./demo12 5005 /tmp/demo12.log\n\n");
		return -1;
	}

	CloseIOAndSignal();
	signal(SIGINT, FathEXIT);
	signal(SIGTERM, FathEXIT);

	if (logfile.Open(argv[2],"a+")==false) { 
		printf("logfile.Open(%s) failed.\n",argv[2]); 
		return -1; 
	}

	// 服务端初始化
	if( TcpServer.InitServer(atoi(argv[1])) == false ){
		logfile.Write("TcpServer.InitServer(%s) failed.\n", argv[1]);
		return -1;
	}
	while (true)
	{
		// 等待客户端的连接请求
		if( TcpServer.Accept() == false ){
			logfile.Write("TcpServer.Accept() failed.\n");
			// return -1;
			FathEXIT(-1);
		}
		logfile.Write("客户端（%s）已连接\n", TcpServer.GetIP());

// logfile.Write("listenfd=%d, connfd=%d\n", TcpServer.m_listenfd, TcpServer.m_connfd);
		
		if(fork() > 0) {
			TcpServer.CloseClient();
			continue;
		}

		signal(SIGINT, ChldEXIT);
		signal(SIGTERM, ChldEXIT);
		
		TcpServer.CloseListen();
// logfile.Write("listenfd=%d, connfd=%d\n", TcpServer.m_listenfd, TcpServer.m_connfd);
// sleep(100);

		// 子进程与客户端通讯，处理业务
		char strrecvbuffer[1024], strsendbuffer[1024];

		// 第5步：与客户端通讯，接收客户端发过来的报文后，回复ok。
		while (1)
		{
			memset(strrecvbuffer, 0, sizeof(strrecvbuffer));
			memset(strsendbuffer, 0, sizeof(strsendbuffer));
			
			if ( TcpServer.Read(strrecvbuffer) == false ) // 接收客户端的请求报文。
			{
				break;
			}
			logfile.Write("接收：%s\n", strrecvbuffer);

			// 处理业务的主函数
			if (_main(strrecvbuffer, strsendbuffer) == false){
				break;
			}

			
			if ( TcpServer.Write(strsendbuffer) == false ) // 向客户端发送响应结果。
			{
				// perror("send");
				break;
			}
			logfile.Write("发送：%s\n", strsendbuffer);
		}

		// return 0;
		ChldEXIT(0);
	}
}

void FathEXIT(int sig){
	// 以下代码是为了防止信号处理函数在执行的过程中被信号中断
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	logfile.Write("父进程退出,sig=%d\n", sig);
	TcpServer.CloseListen();
	kill(0,15);				// 通知全部的子进程退出
	exit(0);
}

void ChldEXIT(int sig){
	// 以下代码是为了防止信号处理函数在执行的过程中被信号中断
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	logfile.Write("子进程退出,sig=%d\n", sig);
	TcpServer.CloseClient();
	exit(0);
}

bool _main(const char *strrecv, char *strsend){
	// 解析strrecvbuffer获取服务代码
	int isrvcode = -1;
	GetXMLBuffer(strrecv, "srvcode", &isrvcode);


	if((isrvcode != 1) && (bsession==false)){
		strcpy(strsend,"<retcode>-1</retcode><message>用户未登录</message>");
		return true;
	}
	// 处理每种业务
	switch (isrvcode)
	{
		case 1:
			srv001(strrecv, strsend);
			break;
		case 2:
			srv002(strrecv, strsend);
			break;
		default:
			logfile.Write("业务代码不合法：%s\n", strrecv);
			return false;
	}
	return true;
}

bool srv001(const char *strrecv, char *strsend){
	// 解析strrecvbuffer获取业务参数
	char tel[21], password[31];
	GetXMLBuffer(strrecv, "tel", tel, 20);
	GetXMLBuffer(strrecv, "password", password, 30);

	// 处理业务
	// 把处理结果生成strsendbuffer
	if( (strcmp(tel, "123456")==0) && (strcmp(password, "123456")==0) ){
		strcpy(strsend, "<retcode>0</retcode><message>成功</message>");
		bsession = true;
	}
	else{
		strcpy(strsend, "<retcode>-1</retcode><message>失败</message>");
	}
	
	return true;
}

bool srv002(const char *strrecv, char *strsend){
	// 解析strrecvbuffer获取业务参数
	char cardid[31];
	GetXMLBuffer(strrecv, "cardid", cardid, 30);

	// 处理业务
	// 把处理结果生成strsendbuffer

	printf("cardid=%s", cardid);
	if( strcmp(cardid, "111111")==0){
		strcpy(strsend, "<retcode>0</retcode><message>成功</message><amount>100.00</amount>");
	}
	else{
		strcpy(strsend, "<retcode>-1</retcode><message>失败</message>");
	}
	
	return true;
}